import xmlrpclib
from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
import random
import sys
import pickle
import timeit

from Tkinter import *

class SETTINGS:
    grandeurUniver=20
    grandeurUniverX=grandeurUniver
    grandeurUniverY=grandeurUniver
    grandeurUniverZ=grandeurUniver
    
    grandeurEcran=600
    grandeurEcranX=grandeurEcran
    grandeurEcranY=grandeurEcran
    
    grandeurSecteur=grandeurUniver
    grandeurSecteurX=grandeurSecteur
    grandeurSecteurY=grandeurSecteur
    grandeurSecteurZ=grandeurSecteur
    
    debutPointDeVue=grandeurUniver/2-grandeurSecteur/2
    debutPointDeVueX=debutPointDeVue
    debutPointDeVueY=debutPointDeVue
    debutPointDeVueZ=0

class VAISSEAU:
    arme=1
    armure=1
    vieMax=100
class VueTkinter(object):
    def __init__(self,parent):
        #parent= (Controleur)
        self.root=Tk()
        self.parent=parent
        
        self.secteur=parent.modele.universOrion.matriceUnites.matrice       
        self.root.title("ORION")    
        
        self.statusBar = Label(self.root, text="Index Temps: ", bd=1, relief=SUNKEN, anchor=W)
        self.statusBar.pack(side=TOP, fill=X)    
        
        self.statusBar2 = Label(self.root, text="Moment Click: Moment Executer: ", bd=1, relief=SUNKEN, anchor=W)
        self.statusBar2.pack(side=TOP, fill=X) 
          
        self.canevas=Canvas(self.root,width=SETTINGS.grandeurEcranX,height=SETTINGS.grandeurEcranY,bg="black")
        self.canevas.pack(side=TOP)
        #menu = Menu(self.root)
        #self.root.config(menu=menu)
        #PrincipalMenu = Menu(menu)
        self.frameMouvement = Frame(self.root)
        self.frameMouvement.pack(side=TOP)       
        self.definirInterfaceControle()
        #self.monTimer()
        #self.afficheSecteur(parent.modele.monPointDeVue.getPointDeVue())
        self.imageVaisseau = PhotoImage(file="rocket.gif")
        
        
        self.tempoTemps=0
        self.tempoAffichage=0
        self.tempoReseau=0
        self.indexTemps=0

        

    #Interface de controle
    
    def afficheDebugInfo(self):
        newStatus="Index Temps: "+str(self.indexTemps)
        self.statusBar.config(text=newStatus)
        #self.statusBar.update_idletasks()
    
    def afficheDebugInfo2(self):
        newStatus="Index Temps: "+str(self.indexTemps)
        self.statusBar2.config(text=newStatus)
        #self.statusBar.update_idletasks()
        
    def definirInterfaceControle(self):
        Button(self.frameMouvement,text="\\",command=self.parent.commandButtonNW).grid(row=0, column=0)
        Button(self.frameMouvement,text="^",command=self.parent.commandButtonN).grid(row=0, column=1)
        Button(self.frameMouvement,text="/",command=self.parent.commandButtonNE).grid(row=0, column=2)
        Button(self.frameMouvement,text="<",command=self.parent.commandButtonW).grid(row=1, column=0)
        
        Button(self.frameMouvement,text=">",command=self.parent.commandButtonE).grid(row=1, column=2)
        Button(self.frameMouvement,text="/",command=self.parent.commandButtonSW).grid(row=2, column=0)
        Button(self.frameMouvement,text="v",command=self.parent.commandButtonS).grid(row=2, column=1)
        Button(self.frameMouvement,text="\\",command=self.parent.commandButtonSE).grid(row=2, column=2)

                        
    def afficher(self):
        self.effaceEcran()
        self.afficheDebugInfo()
        for x in range(SETTINGS.grandeurSecteurX):
            for y in range(SETTINGS.grandeurSecteurY):
                if (self.secteur[x][y]!=None):
                    self.afficherUnite(x,y,600/20,"white")
                        
    def afficherEtoile(self,x,y,tailleEtoile):
        #tailleEtoile=12
        decalageX=1
        decalageY=2        
        self.canevas.create_oval(x*tailleEtoile+decalageX,y*tailleEtoile+decalageY,x*tailleEtoile+decalageX+tailleEtoile,y*tailleEtoile+decalageY+tailleEtoile, fill='white')      

    def afficherUnite(self,x,y,tailleUnite,couleur):
        #tailleEtoile=12
        decalageX=1
        decalageY=2      
        #self.canevas.create_image(x*tailleUnite+decalageX,y*tailleUnite+decalageY, anchor=NW,image=self.imageVaisseau)  
        self.canevas.create_image( x*tailleUnite+decalageX, y*tailleUnite+decalageY, anchor=NW, image=self.imageVaisseau )
        #self.canevas.create_oval(x*tailleUnite+decalageX,y*tailleUnite+decalageY,x*tailleUnite+decalageX+tailleUnite,y*tailleUnite+decalageY+tailleUnite, fill=couleur)  
    def effaceEcran(self):
        self.canevas.delete(ALL)
#   
    def callTimer(self):
        self.indexTemps+=1            
        self.parent.jouerTours()                
        self.afficher()            
        self.root.after(1000, self.callTimer)      
#####  Controleur #####       
class Controleur(object):
    def __init__(self):
        self.server = xmlrpclib.ServerProxy('http://localhost:8000')
        self.trameTours=[None,None,None,None,None,None]
        self.listeActionsEncours=[]
        self.modele=ModelePartie(self) 
        #self.trameTemps=0            
        self.vue=VueTkinter(self)
        self.focus=self.modele.vaisseau1 
        self.demarrer() 
               
    def demarrer(self):
        self.vue.callTimer()
        self.vue.root.mainloop()
        
        
    def unecomande(self):
        print "HOURAAAAAAAA"
    
    def jouerTours(self):
        self.trameTours.append(None)
        #self.contacterServeur()
        if self.trameTours[self.vue.indexTemps]!=None:
            #print "jouerTours: "+str(self.vue.indexTemps)  
            self.trameTours[self.vue.indexTemps]()
            #print "jouerTours: "+str(self.vue.indexTemps)
            #print "********************"

    
    def inscrireCommande(self,action):
        #print "inscrireCommande: "+str(self.vue.indexTemps)        
        self.trameTours[self.vue.indexTemps+2]=action
        #roro = self.server.inscrireCommandeAt(action, self.vue.indexTemps+5)
        #print "inscrireCommande: "  
        #print "********************"
       
    def pingTest(self):
        roro = self.server.pingTest()  
           
    def contacterServeur(self):
        #print "inscrireCommande: "+str(self.vue.indexTemps)        
        #self.trameTours[self.vue.indexTemps+5]=action
        #roro = self.server.inscrireCommandeAt(action, self.vue.indexTemps+5)
        action=self.trameTours[self.vue.indexTemps+2]
        if action!=None:
            roro = self.server.inscrireCommandeAt(action, self.vue.indexTemps+2)
        else:
            action=self.rien
            roro = self.server.inscrireCommandeAt(action, self.vue.indexTemps+2)
        #print "inscrireCommande: "+roro  
        #print "********************"

    def creerTrameDesTours(self):
        #Creer deux premeirs tours
        self.trameTours=[None,None,None,None,None,None]
  

    def commandButtonNW(self):    
        self.inscrireCommande(self.bougerNW)
        
    def commandButtonN(self):    
        self.inscrireCommande(self.bougerN)       
    
    def commandButtonNE(self):    
        self.inscrireCommande(self.bougerNE)          
    
    def commandButtonW(self):    
        self.inscrireCommande(self.bougerW)   
                
    def commandButtonE(self):    
        self.inscrireCommande(self.bougerE)   
        
    def commandButtonSW(self):    
        self.inscrireCommande(self.bougerSW)   
         
    def commandButtonS(self):    
        self.inscrireCommande(self.bougerS)    
        
    def commandButtonSE(self):    
        self.inscrireCommande(self.bougerSE)   
        
    def bougerNW(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,-1,-1)
        
    def bougerN(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,0,-1)
       
    def bougerNE(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,1,-1)     
       
    def bougerW(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,-1,0)      
                
    def bougerE(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,1,0)
        
    def bougerSW(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,-1,1)   
         
    def bougerS(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,0,1)           
  
    def bougerSE(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,1,1)     

    def rien(self):    
           pass
class Coup(object):
    def __init__(self,unite,action):
        self.unite=unite
        self.action=action       

#####  Modele #####  

class ModelePartie(object):   
    def __init__(self, parent):
        #parent = (Controleur0  
        self.parent=parent     
        self.universOrion=Univers(self)
        self.listeClasses=self.creerListeDesClasses()
        #Placer joueurs de depart
        self.vaisseau1=Unite("vaisseau",self.listeClasses['vaisseau'].vieMax,0,10,1)
        self.universOrion.ajouterUnite(self.vaisseau1)
        
    def creerListeDesClasses(self):
        listeClasses={}
        listeClasses['vaisseau']=Classe(VAISSEAU.arme,VAISSEAU.armure,VAISSEAU.vieMax)
        return listeClasses
    
class Classe(object):
    def __init__(self,arme,armure,vieMax):
        #self.armure1=10
        self.arme=arme
        self.armure=armure
        self.vieMax=vieMax
        
class Unite(object):
    #Creation matrice x*y initialise a 0
    def __init__(self, classe,vieMax,positionX,positionY,couleur):
        self.classe=classe
        self.vieMaintenant=vieMax
        self.positionX=positionX
        self.positionY=positionY
        self.couleur=couleur
        self.vivant=True
        self.tacheActive=None
        
        
    def executerTache(self):
        self.tacheActive()
    
    def bougerNW(self): 
        self.positionX+=(-1)   
        self.positionY+=(-1) 
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,-1,-1)
        
    def bougerN(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,0,-1)
       
    def bougerNE(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,1,-1)     
       
    def bougerW(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,-1,0)      
                
    def bougerE(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,1,0)
        
    def bougerSW(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,-1,1)   
         
    def bougerS(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,0,1)           
  
    def bougerSE(self):    
        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,1,1)       
        
        
class Univers(object):
    #Creation matrice x*y initialise a 0
    def __init__(self, parent):
        self.matriceUnites=Matrice2D(SETTINGS.grandeurUniverX,SETTINGS.grandeurUniverY)
    
    def ajouterUnite(self,unite):
        self.matriceUnites.matrice[unite.positionX][unite.positionY]=unite
        
    def bougerUnite(self,positionX,positionY,deplacementX,deplacementY):
        if 0<=positionX+deplacementX<self.matriceUnites.grandeurX:
            if 0<=positionY+deplacementY<self.matriceUnites.grandeurY:           
                #updater position X et Y dans unite
                self.matriceUnites.matrice[positionX][positionY].positionX+=deplacementX
                self.matriceUnites.matrice[positionX][positionY].positionY+=deplacementY
                #Updater arrivee dans matrice
                self.matriceUnites.matrice[positionX+deplacementX][positionY+deplacementY]=self.matriceUnites.matrice[positionX][positionY]
                #Updater depart dans matrice
                self.matriceUnites.matrice[positionX][positionY]=None
        return self.matriceUnites.matrice
        



class Joueur(object):
    #Creation matrice x*y initialise a 0
    def __init__(self, couleur):
        self.couleur=couleur
        #self.niveauArmure=1
        #self.niveauArme=1    
            

   
    
class Matrice2D(object):
    #Creation matrice x*y initialise a 0
            
    def __init__(self,grandeurX,grandeurY):
        self.grandeurX=grandeurX
        self.grandeurY=grandeurY
        self.matrice=self.creer(grandeurX,grandeurY)
               
    def creer(self,grandeurX,grandeurY):
        matrice=[]
        for x in range(grandeurX):
            matrice.append([])
            for y in range(grandeurY):
                matrice[x].append(None)
        return matrice
               
#####  VueGraphique  #####              
                                 
#####  FIN VueGraphique  #####    

if __name__ == '__main__':
        controleur=Controleur()
#Ordre
#
#quandDemande
#parQui
#utiliserQuoi
#faireQuelleAction            
#    def tick(self):
#        self.bougerEtoile()
#        self.after(200, tick)        
        #maMatrice=Matrice2D(SETTINGS.grandeurUniver,SETTINGS.grandeurUniver)
#print maMatrice.matrice


#s = xmlrpclib.ServerProxy('http://localhost:8000')

#print s.additionne(2,3)  
#print s.monTexte("Gonzalo")


#pkl_file = open(s.testToto(), 'rb')

#dataX1 = pickle.load(pkl_file)
#pprint.pprint(dataX1)


#pkl_file.close()
#received=s.getUnivers()
#universSimple=pickle.loads(received)


#print universSimple

#maNouvelleListe=universOrion.getMatriceSimple()
#for x in maNouvelleListe
#print universOrion
#monPickle= s.testToto()
#print monUnivers
#etoile = pickle.load(monPickle)

# Imprimer la liste des methodes disponibles
#print s.system.listMethods()

#    def commandButtonNW(self):    
#        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,-1,-1)
#        self.vue.afficher()
#        
#    def commandButtonN(self):    
#        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,0,-1)
#        self.vue.afficher()
#        
#    def commandButtonNE(self):    
#        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,1,-1)     
#        self.vue.afficher()   
#        
#    def commandButtonW(self):    
#        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,-1,0)      
#        self.vue.afficher() 
#                
#    def commandButtonE(self):    
#        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,1,0)
#        self.vue.afficher() 
#        
#    def commandButtonSW(self):    
#        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,-1,1)   
#        self.vue.afficher()  
#         
#    def commandButtonS(self):    
#        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,0,1)           
#        self.vue.afficher()   
#        
#    def commandButtonSE(self):    
#        secteur=self.modele.universOrion.bougerUnite(self.focus.positionX,self.focus.positionY,1,1)     
#        self.vue.afficher()    

   
#    def afficherDepart(self):
#        self.effaceEcran()
#        for x in range(SETTINGS.grandeurSecteurX):
#            for y in range(SETTINGS.grandeurSecteurY):
#                if (self.secteur[x][y]!=None):
#                    self.afficherUnite(x,y,600/20,"white")

        #self.fileDesTours.append([None,None])
        #print self.trameTours[self.vue.indexTemps]
                #print self.vue.indexTemps
        #creerappend avec slot joueurs
        #self.trameTours.append([None,None])
        
    #self.inscrireCommande(self.trameTemps,1,vaisseau,"bougerE")   
#####  Controleur #####   

#Ordre
#
#quandDemande
#parQui
#utiliserQuoi
#faireQuelleAction
        #self.bougerEtoile()       
        #self.tempoTemps+=1  
        #self.tempoReseau+=1     
#        if self.tempoTemps == 2:
#            self.tempoTemps=0
#            self.indexTemps+=1
#            #print "Coup No: "+str(self.indexTemps)
#            self.parent.jouerTours()            
        #if self.tempoReseau == 5:
            #self.tempoReseau=0
            #print "Update Reseau" 
            #print "Coup No: "+str(self.indexTemps)